package ca.etsmtl.logti.log619.lab05.utilities;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;

import javax.mail.Address;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;

/**
 * @author Simon Lanoie
 */
public class BayesFilterBuilder {

	static final String COURRIELS_CLASSES = "data/courriels-classes";
	
	public static HashMap<String, Word> wordDatabase = new HashMap<String, Word>();
	public static ArrayList<String> spamSenders = new ArrayList<String>();
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {

		browseMailList();

		for (Word word : wordDatabase.values()) {
			
			word.calcBadProb(wordDatabase.values().size());
			word.calcGoodProb(wordDatabase.values().size());
			word.finalizeProb();
			
			System.out.println("WORD: "+word.getWord()+" "+word.getPSpam());
		}
		
		System.out.println("Number of words in database: "+wordDatabase.size());
		System.out.println("Number of senders in blacklist: "+spamSenders.size());
	}

	public static void buildDatabase(){
		
		browseMailList();
		
		for (Word word : wordDatabase.values()) {
			
			word.calcBadProb(wordDatabase.values().size());
			word.calcGoodProb(wordDatabase.values().size());
			word.finalizeProb();
		}
	}
	
	private static void browseMailList(){
		
	    try {
	    	
	    	FileInputStream fstream = new FileInputStream(COURRIELS_CLASSES);
			
		    DataInputStream in = new DataInputStream(fstream);
		    BufferedReader br = new BufferedReader(new InputStreamReader(in));
		    
		    BufferedInputStream curEmail = null;
		    
		    String strLine;
		    String type;
		    String directory;
		    Session mimeSession = null;
		    
		    int messageProcessedCount = 0;
			while ((strLine = br.readLine()) != null)   {
				
				type = strLine.substring(0, strLine.indexOf(" ")).trim();
				directory = strLine.substring(strLine.indexOf(" "), strLine.length()).trim();
				
				try {
					curEmail = new BufferedInputStream(new FileInputStream("data/"+directory));
					MimeMessage msg = new MimeMessage(mimeSession, curEmail);
					
					String[] content = null;
					try {
						content = EmailSplicer.getMessageContent(msg);
					}
					catch (UnsupportedEncodingException e) {
						// TODO Auto-generated catch block
						continue;
					}
					
					if(type.equals("spam")){
						
						Address[] spamAdress = msg.getFrom();
						String emailAddress = spamAdress[0].toString();
						emailAddress = emailAddress.replaceAll(">", "");
						emailAddress = emailAddress.replaceAll("<", "");
						emailAddress = emailAddress.substring(emailAddress.lastIndexOf(" ")+1, emailAddress.length());
						
						// Keeping sender email adress
						if(!spamSenders.contains(emailAddress))	{
							spamSenders.add(emailAddress);
						}
					}
					
					// Bayes 
					for (int i = 0; i < content.length; i++) {
						
						// Splitting line into multiple words
						String[] words = content[i].trim().split(" ");
						
						for (int j = 0; j < words.length; j++) {
							
							String trim = words[j].replace(",", "");
							trim = trim.replace(".", "");
							trim = trim.replace("?", "");
							trim = trim.replace("!", "");
							trim = trim.replace(":", "");
							trim = trim.replace("\"", "");
							trim = trim.replace("/", "");
							trim = trim.replace("{", "");
							trim = trim.replace("}", "");
							trim = trim.replace("[", "");
							trim = trim.replace("]", "");
							trim = trim.replace("(", "");
							trim = trim.replace(")", "");
							trim = trim.replace(">", "");
							trim = trim.replace("<", "");
							trim = trim.replace("*", "");
							trim = trim.replace("=", "");
							trim = trim.replace("-", "");
							trim = trim.replace("+", "");
							trim = trim.replace("$", "");
							
							trim = trim.replace("\\n","");
							trim = trim.replace("\\t","");
							trim = trim.replace(" ","");
							trim = trim.replace("__________", "");
							
							String word = trim.trim().toLowerCase();
							
							boolean isValidWord = true;
							char [] letters = word.toCharArray();
							
							if(letters.length == 1)
								isValidWord = false;
							
							for (int c = 0; c < letters.length; c++) {
								
								
								if(Character.isDigit(letters[c])){
									
									isValidWord = false;
									break;
								}
								
								if(letters[c] == '@'){
									isValidWord = false;
									break;
								}
							}
							
							if(!word.isEmpty() && isValidWord){
								
								// Word already exist
								if(wordDatabase.containsKey(word)){
									Word wordObject = wordDatabase.get(word);
									
									if(type.equals("ham")){
										wordObject.countGood();	
									}
									else {
										wordObject.countBad();
									}
								}
								// Adding word to database
								else {
									Word wordObject = new Word(word);
									
									if(type.equals("ham")){
										wordObject.countGood();	
									}
									else {
										wordObject.countBad();
									}
									
									wordDatabase.put(word, wordObject);
								}
							}
						}
					}
					curEmail.close();
					
				} catch (MessagingException e) {
//					// TODO Auto-generated catch block
//					e.printStackTrace();
//					System.err.println(e.getMessage());
				}
				
				messageProcessedCount++;
			}
			
			fstream.close();
			br.close();
		    in.close();	
		    
		    System.out.println("NUMBER OF MESSAGES PROCESSED: "+messageProcessedCount);
		    
		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//			System.err.println(e.getMessage());
		}
	}

}
